package com.ywu.standard.gateway.filter;

import com.ywu.common.gson.GsonUtils;
import com.ywu.common.result.CommonResult;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * @ClassName CustomTimeoutFilter
 * @Description TODO
 * @Author GroundDemo
 * @Date 2025/4/17 11:43
 * @Version 1.0
 **/
@Component
public class CustomTimeoutFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange)
                .onErrorResume(throwable -> {
                    if (throwable instanceof ResponseStatusException) {
                        ResponseStatusException responseStatusException = (ResponseStatusException) throwable;
                        HttpStatus status = responseStatusException.getStatus();
                        int value = status.value();
                        if (value == HttpStatus.GATEWAY_TIMEOUT.value()) {
                            // 如果状态码为超时状态码，则返回自定义对象
                            ServerHttpResponse response = exchange.getResponse();
                            response.setStatusCode(HttpStatus.GATEWAY_TIMEOUT);
                            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                            String errorMessage = GsonUtils.serialize(CommonResult.error().setCode("504").setErrorCode("request.timeout.out").setMessage("request time out"));
                            DataBuffer buffer = response.bufferFactory().wrap(errorMessage.getBytes(StandardCharsets.UTF_8));
                            return response.writeWith(Mono.just(buffer));
                        }
                    }
                    return Mono.error(throwable);
                });
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
